13장 스코프


모든 식별자는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효 범위가 결정된다. 즉, 스코프는 식별자가 유효한 범위를 말한다.

var x = 'global';

function foo() {
  var x = 'local';
  console.log(x); // ①
}

foo();

console.log(x); // ②

위의 코드에서 JS 엔진은 x 를 어떤 변수를 참조해야할 것인지 결정해야 한다. 이를 식별자 결정 이라고 한다. 스코프는 식별자 결정을 할때 사용되는 규칙이다.

Untitled 15.png|Untitled 15.png

코드에서 x는 다른 스코프에 선언되어 충돌되지 않는다.
같은 스코프안에서는 같은 이름의 식별자를 사용할 수 없다.
var 은 같은 스코프내에서 중복 선언이 허용되지만, let과 const 는 같은 스코프 내에서 중복 선언을 허용하지 않는다.

스코프의 종류

Untitled 1 9.png|Untitled 1 9.png

전역 변수는 어디서든지 참조할 수 있음.
지역 변수는 자신의 지역 스코프와 하위 지역 스코프에서 유효

스코프 체인

함수 중첩되면 지역 스코프 중첩되는데, 이 중첩에 의해 계층적 구조를 갖는다. 이를 스코프 체인이라고 함.
Untitled 2 8.png|300

변수를 참조할 때 JS 엔진이 스코프 체인 따라 올라가면서 변수를 검색함.

스코프 체인은 물리적인 실체로 존재한다. JS 엔진은 코드 실행하기 전에 그림과 유사한 렉시컬 환경을 생성하고, 변수가 선언되면 렉시컬 환경에 key value 형태로 등록된다.

상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조가능, but 반대는 안됨.
함수도 변수와 마찬가지.

함수 레벨 스코프

var로 선언된 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정. 이러한 특성을 함수 레벨 스코프 라고 한다.

let, const 는 블록 레벨 스코프를 지원한다. 즉, 블록단위의 문(if, for 등등) 을 모두 지역 스코프로 인정한다는 것이다.

렉시컬 스코프

var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // ?
bar(); // ?

실행 결과가 bar 함수의 상위 스코프를 어떻게 정의 하느냐에 따라서 달라진다.

  1. 함수를 어디서 호출했는지에 따라 함수의 상위 스코프를 결정
  2. 함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정 (JS)
    첫번째 방식을 동적 스코프라하고, 두번째 방식을 렉시컬 스코프 or 정적 스코프라고 한다.

JS 에서는 렉시컬 스코프르 따른다.

함수의 상위 스코프는 함수 정의가 실행될 때 정적으로 결정됨. 함수 정의가 실행되어 생성된 함수 객체는 결정된 상위 스코프를 기억한다.

reference